﻿
Imports std

'with { and }, do not care whether there is blank characters before { and after }
Public Class paragraph
    Inherits iScript
    Implements iInvokeable

    Public Const start As Char = character.leftBrace
    Public Const [end] As Char = character.rightBrace
    Public Const lineSeparator As Char = character.semicolon

    Protected Friend Shared Function _isMeaningfulMark(ByVal c As Char) As Boolean
        Return isstart(c) OrElse isend(c)
    End Function

    Private sentences As vector(Of sentence) = Nothing

    Private Sub New(ByVal ss As vector(Of sentence))
        sentences = ss
    End Sub

    Private Sub New(ByVal s As sentence)
        Me.New(New vector(Of sentence))
        sentences.push_back(s)
    End Sub

    Protected Overrides Function invokeImpl(ByVal ctx As context) As Boolean
        Dim i As Int64
        For i = 0 To sentences.size() - 1
            If Not sentences(i).invoke(ctx) Then
                Return False
            End If
        Next

        Return True
    End Function

    Public Function invoke(ByVal ctx As context) As Boolean Implements iInvokeable.invoke
        Return invokebase(ctx)
    End Function

    Private Shared Function isstart(ByVal c As Char) As Boolean
        Return c = start
    End Function

    Private Shared Function isend(ByVal c As Char) As Boolean
        Return c = [end]
    End Function

    Protected Shared Function parseImpl(ByVal input As String, ByRef index As Int64, _
                                        ByRef output As paragraph) As Boolean
        If token(input, index, Nothing, AddressOf isstart, AddressOf [false]) Then
            Dim vs As vector(Of sentence) = Nothing
            vs = New vector(Of sentence)()
            Dim s As sentence = Nothing
            While sentence.parse(input, index, s)
                vs.push_back(s)
                s = Nothing
            End While
            If token(input, index, Nothing, AddressOf isend, AddressOf [false]) Then
                output = New paragraph(vs)
                Return True
            Else
                Return False
            End If
        Else
            Dim s As sentence = Nothing
            If sentence.parse(input, index, s) Then
                output = New paragraph(s)
                Return True
            Else
                Return False
            End If
        End If
    End Function

    Protected Overrides Sub setsource(ByVal script As String, ByVal start As Long, ByVal [end] As Long)
        'do not set source for a paragraph
    End Sub

    Public Shared Function parse(ByVal input As String, ByRef index As Int64, ByRef output As paragraph) As Boolean
        Return parsebase(input, index, output, AddressOf parseImpl)
    End Function
End Class
